using System;
using System.Collections.Generic;
using Me.Prettyprint.Cassandra.Serializers;
using Me.Prettyprint.Hector.Api;
using Me.Prettyprint.Hector.Api.Beans;

namespace Me.Prettyprint.Hector.Api.Mutation
{
    /// <summary>
    /// A Mutator inserts or deletes values from the cluster.
    /// There are two main ways to use a mutator:
    /// 1. Use the insert/delete methods to immediately insert of delete values.
    /// or 2. Use the addInsertion/addDeletion methods to schedule batch operations and then execute()
    /// all of them in batch.
    /// The class is not thread-safe.
    /// </summary>
    /// <typeparam name="K"></typeparam>
	public interface Mutator<K>
	{
        MutationResult Insert<N,V>(K key, string cf, HColumn<N,V> hcol);
        MutationResult Insert<SN,N,V>(K key, string cf, HSuperColumn<SN, N, V> superColumn);
        MutationResult Delete<N>(K key, string cf, N columnName, Serializer<N> nameSerializer);
        MutationResult SubDelete<SN,N>(K key, string cf, SN supercolumnName, N columnName, Serializer<SN> sNameSerializer, Serializer<N> nameSerializer);
        MutationResult SuperDelete<SN>(K key, string cf, SN supercolumnName, Serializer<SN> sNameSerializer);
        Mutator<K> AddSuperDelete<SN>(K key, string cf, SN sColumnName, Serializer<SN> sNameSerializer);
        Mutator<K> AddInsertion<N,V>(K key, string cf, HColumn<N, V> c);
        Mutator<K> AddInsertion<SN, N, V>(K key, string cf, HSuperColumn<SN, N, V> sc);
        Mutator<K> AddDeletion<N>(K key, string cf, N columnName, Serializer<N> nameSerializer);
        Mutator<K> AddDeletion<N>(K key, string cf);
        Mutator<K> AddDeletion<N>(IEnumerable<K> keys, string cf);
        Mutator<K> AddDeletion<N>(IEnumerable<K> keys, string cf, long clock);
        Mutator<K> AddDeletion<N>(K key, string cf, long clock);
        Mutator<K> AddDeletion<N>(K key, string cf, N columnName, Serializer<N> nameSerializer, long clock);
        Mutator<K> AddSubDelete<SN,N,V>(K key, string cf, HSuperColumn<SN,N,V> sc);
        Mutator<K> AddSubDelete<SN,N,V>(K key, string cf, HSuperColumn<SN, N, V> sc, long clock);
        Mutator<K> AddSubDelete<SN,N>(K key, string cf, SN sColumnName, N columnName, Serializer<SN> sNameSerializer, Serializer<N> nameSerialer);
        Mutator<K> AddSubDelete<SN,N>(K key, string cf, SN sColumnName, N columnName, Serializer<SN> sNameSerializer, Serializer<N> nameSerialer, long clock);
        MutationResult Execute();
        Mutator<K> DiscardPendingMutations();
        MutationResult InsertCounter<N>(K key, string cf, HCounterColumn<N> c);
        MutationResult InsertCounter<SN, N>(K key, string cf, HCounterSuperColumn<SN, N> superColumn);
        MutationResult IncrementCounter<N>(K key, string cf, N columnName, long increment);
        MutationResult DecrementCounter<N>(K key, string cf, N columnName, long increment);
        MutationResult DeleteCounter<N>(K key, string cf, N columnName, Serializer<N> nameSerializer);
        MutationResult SubDeleteCounter<SN, N>(K key, string cf, SN supercolumnName, N columnName, Serializer<SN> sNameSerializer, Serializer<N> nameSerializer);
        Mutator<K> AddCounter<N>(K key, string cf, HCounterColumn<N> c);
        Mutator<K> AddCounter<SN, N>(K key, string cf, HCounterSuperColumn<SN, N> sc);
        Mutator<K> AddCounterDeletion<N>(K key, string cf, N counterColumnName, Serializer<N> nameSerializer);
        Mutator<K> AddCounterDeletion(K key, string cf);
        Mutator<K> AddCounterSubDeletion<SN, N>(K key, string cf, HCounterSuperColumn<SN, N> sc);
        int GetPendingMutationCount();
	}
}